package com.powernode.teatraceability.raw;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.fisco.bcos.sdk.abi.FunctionReturnDecoder;
import org.fisco.bcos.sdk.abi.TypeReference;
import org.fisco.bcos.sdk.abi.datatypes.Address;
import org.fisco.bcos.sdk.abi.datatypes.Bool;
import org.fisco.bcos.sdk.abi.datatypes.Event;
import org.fisco.bcos.sdk.abi.datatypes.Function;
import org.fisco.bcos.sdk.abi.datatypes.Type;
import org.fisco.bcos.sdk.abi.datatypes.Utf8String;
import org.fisco.bcos.sdk.abi.datatypes.generated.Uint256;
import org.fisco.bcos.sdk.abi.datatypes.generated.tuples.generated.Tuple2;
import org.fisco.bcos.sdk.abi.datatypes.generated.tuples.generated.Tuple5;
import org.fisco.bcos.sdk.abi.datatypes.generated.tuples.generated.Tuple6;
import org.fisco.bcos.sdk.abi.datatypes.generated.tuples.generated.Tuple7;
import org.fisco.bcos.sdk.client.Client;
import org.fisco.bcos.sdk.contract.Contract;
import org.fisco.bcos.sdk.crypto.CryptoSuite;
import org.fisco.bcos.sdk.crypto.keypair.CryptoKeyPair;
import org.fisco.bcos.sdk.eventsub.EventCallback;
import org.fisco.bcos.sdk.model.CryptoType;
import org.fisco.bcos.sdk.model.TransactionReceipt;
import org.fisco.bcos.sdk.model.callback.TransactionCallback;
import org.fisco.bcos.sdk.transaction.model.exception.ContractException;

@SuppressWarnings("unchecked")
public class Product extends Contract {
    public static final String[] BINARY_ARRAY = {"608060405234801561001057600080fd5b50611ccb806100206000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c8063427e4efc1461005c5780638fb2f8381461030657806391321f7514610354578063b78aff8e146105f4578063c7310f9c14610844575b600080fd5b610304600480360360c081101561007257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156100b957600080fd5b8201836020820111156100cb57600080fd5b803590602001918460018302840111640100000000831117156100ed57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192908035906020019064010000000081111561015057600080fd5b82018360208201111561016257600080fd5b8035906020019184600183028401116401000000008311171561018457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803590602001906401000000008111156101e757600080fd5b8201836020820111156101f957600080fd5b8035906020019184600183028401116401000000008311171561021b57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192908035906020019064010000000081111561027e57600080fd5b82018360208201111561029057600080fd5b803590602001918460018302840111640100000000831117156102b257600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050610a94565b005b6103526004803603604081101561031c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610e58565b005b6105f2600480360360a081101561036a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001906401000000008111156103a757600080fd5b8201836020820111156103b957600080fd5b803590602001918460018302840111640100000000831117156103db57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192908035906020019064010000000081111561043e57600080fd5b82018360208201111561045057600080fd5b8035906020019184600183028401116401000000008311171561047257600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803590602001906401000000008111156104d557600080fd5b8201836020820111156104e757600080fd5b8035906020019184600183028401116401000000008311171561050957600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192908035906020019064010000000081111561056c57600080fd5b82018360208201111561057e57600080fd5b803590602001918460018302840111640100000000831117156105a057600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929050505061115b565b005b6106406004803603604081101561060a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506113cc565b604051808873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001806020018060200180602001806020018781526020018615151515815260200185810385528b818151815260200191508051906020019080838360005b838110156106ce5780820151818401526020810190506106b3565b50505050905090810190601f1680156106fb5780820380516001836020036101000a031916815260200191505b5085810384528a818151815260200191508051906020019080838360005b83811015610734578082015181840152602081019050610719565b50505050905090810190601f1680156107615780820380516001836020036101000a031916815260200191505b50858103835289818151815260200191508051906020019080838360005b8381101561079a57808201518184015260208101905061077f565b50505050905090810190601f1680156107c75780820380516001836020036101000a031916815260200191505b50858103825288818151815260200191508051906020019080838360005b838110156108005780820151818401526020810190506107e5565b50505050905090810190601f16801561082d5780820380516001836020036101000a031916815260200191505b509b50505050505050505050505060405180910390f35b6108906004803603604081101561085a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506116b5565b604051808873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001806020018060200180602001878152602001861515151581526020018060200185810385528b818151815260200191508051906020019080838360005b8381101561091e578082015181840152602081019050610903565b50505050905090810190601f16801561094b5780820380516001836020036101000a031916815260200191505b5085810384528a818151815260200191508051906020019080838360005b83811015610984578082015181840152602081019050610969565b50505050905090810190601f1680156109b15780820380516001836020036101000a031916815260200191505b50858103835289818151815260200191508051906020019080838360005b838110156109ea5780820151818401526020810190506109cf565b50505050905090810190601f168015610a175780820380516001836020036101000a031916815260200191505b50858103825286818151815260200191508051906020019080838360005b83811015610a50578082015181840152602081019050610a35565b50505050905090810190601f168015610a7d5780820380516001836020036101000a031916815260200191505b509b50505050505050505050505060405180910390f35b6000851015610b0b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f7468697320696e64657820697320696e76616c6964210000000000000000000081525060200191505060405180910390fd5b6000808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490508510610bc1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f50726f6475637420646f6573206e6f742065786973740000000000000000000081525060200191505060405180910390fd5b6000808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208581548110610c0a57fe5b906000526020600020906007020160060160009054906101000a900460ff1615610c9c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f50726f6475637420616c726561647920636f6e6669726d65640000000000000081525060200191505060405180910390fd5b60008060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208681548110610ce757fe5b9060005260206000209060070201905084816001019080519060200190610d0f929190611b9b565b5083816003019080519060200190610d28929190611b9b565b5082816004019080519060200190610d41929190611b9b565b5081816002019080519060200190610d5a929190611b9b565b507f2e012fb4e01414f3507d1a0c4e0a56b6dd548a48c0f9b77b34b0b12a81c87f8d8160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1686604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200180602001828103825283818151815260200191508051906020019080838360005b83811015610e14578082015181840152602081019050610df9565b50505050905090810190601f168015610e415780820380516001836020036101000a031916815260200191505b50935050505060405180910390a150505050505050565b6000811015610ecf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f7468697320696e64657820697320696e76616c6964210000000000000000000081525060200191505060405180910390fd5b6000808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490508110610f85576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f50726f6475637420646f6573206e6f742065786973740000000000000000000081525060200191505060405180910390fd5b6000808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208181548110610fce57fe5b9060005260206000209060070201600601","60009054906101000a900460ff1615611060576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f50726f6475637420616c726561647920636f6e6669726d65640000000000000081525060200191505060405180910390fd5b60008060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002082815481106110ab57fe5b9060005260206000209060070201905060018160060160006101000a81548160ff0219169083151502179055508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fcd1fb4071437731d51f88c65b1acbb58dd8521b12e12550b9c68c1bfb27546f860405160405180910390a3505050565b6000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060e001604052808773ffffffffffffffffffffffffffffffffffffffff16815260200186815260200183815260200185815260200184815260200142815260200160001515815250908060018154018082558091505060019003906000526020600020906007020160009091909190915060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151816001019080519060200190611271929190611b9b565b50604082015181600201908051906020019061128e929190611b9b565b5060608201518160030190805190602001906112ab929190611b9b565b5060808201518160040190805190602001906112c8929190611b9b565b5060a0820151816005015560c08201518160060160006101000a81548160ff02191690831515021790555050507f811220fceaac876f95cfea72ffd08637842d27046e2e70af8ee7393496732b0a8585604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561138a57808201518184015260208101905061136f565b50505050905090810190601f1680156113b75780820380516001836020036101000a031916815260200191505b50935050505060405180910390a15050505050565b600060205281600052604060002081815481106113e557fe5b9060005260206000209060070201600091509150508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690806001018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156114b85780601f1061148d576101008083540402835291602001916114b8565b820191906000526020600020905b81548152906001019060200180831161149b57829003601f168201915b505050505090806002018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156115565780601f1061152b57610100808354040283529160200191611556565b820191906000526020600020905b81548152906001019060200180831161153957829003601f168201915b505050505090806003018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156115f45780601f106115c9576101008083540402835291602001916115f4565b820191906000526020600020905b8154815290600101906020018083116115d757829003601f168201915b505050505090806004018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156116925780601f1061166757610100808354040283529160200191611692565b820191906000526020600020905b81548152906001019060200180831161167557829003601f168201915b5050505050908060050154908060060160009054906101000a900460ff16905087565b6000606080606060008060606000881015611738576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f7468697320696e64657820697320696e76616c6964210000000000000000000081525060200191505060405180910390fd5b6000808a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054905088106117ee576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f50726f6475637420646f6573206e6f742065786973740000000000000000000081525060200191505060405180910390fd5b6117f6611c1b565b6000808b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020898154811061183f57fe5b90600052602060002090600702016040518060e00160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600182018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156119475780601f1061191c57610100808354040283529160200191611947565b820191906000526020600020905b81548152906001019060200180831161192a57829003601f168201915b50505050508152602001600282018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156119e95780601f106119be576101008083540402835291602001916119e9565b820191906000526020600020905b8154815290600101906020018083116119cc57829003601f168201915b50505050508152602001600382018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611a8b5780601f10611a6057610100808354040283529160200191611a8b565b820191906000526020600020905b815481529060010190602001808311611a6e57829003601f168201915b50505050508152602001600482018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611b2d5780601f10611b0257610100808354040283529160200191611b2d565b820191906000526020600020905b815481529060010190602001808311611b1057829003601f168201915b50505050508152602001600582015481526020016006820160009054906101000a900460ff161515151581525050905080600001518160200151826060015183608001518460a001518560c00151866040015197509750975097509750975097505092959891949750929550565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10611bdc57805160ff1916838001178555611c0a565b82800160010185558215611c0a579182015b82811115611c09578251825591602001919060010190611bee565b5b509050611c179190611c70565b5090565b6040518060e00160405280600073ffffffffffffffffffffffffffffffffffffffff16815260200160608152602001606081526020016060815260200160608152602001600081526020016000151581525090565b611c9291905b80821115611c8e576000816000905550600101611c76565b5090565b9056fea26469706673582212200abb89b43f33badbd5e5fdc90e0ca29f0adc769915fffecf108d137c3bdf6b8f64736f6c634300060a0033"};

    public static final String BINARY = org.fisco.bcos.sdk.utils.StringUtils.joinAll("", BINARY_ARRAY);

    public static final String[] SM_BINARY_ARRAY = {};

    public static final String SM_BINARY = org.fisco.bcos.sdk.utils.StringUtils.joinAll("", SM_BINARY_ARRAY);

    public static final String[] ABI_ARRAY = {"[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"productAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"name\":\"ProductCertificateApplied\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"entityAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"productAddress\",\"type\":\"address\"}],\"name\":\"ProductCertificateApproved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"productAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"name\":\"ProductCertificateChanged\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_productAddress\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_certificateType\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_certificateMaterial\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_enterpriseName\",\"type\":\"string\"}],\"name\":\"applyProductCertificate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"approveProductCertificate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_certificateType\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_certificateMaterial\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_enterpriseName\",\"type\":\"string\"}],\"name\":\"changeProductCertificate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getProductCertificate\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"productAddress\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"certificateType\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"certificateMaterial\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"certificateTime\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"certificateStatus\",\"type\":\"bool\"},{\"internalType\":\"string\",\"name\":\"enterpriseName\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"productCertificates\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"productAddress\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"enterpriseName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"certificateType\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"certificateMaterial\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"certificateTime\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"certificateStatus\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]"};

    public static final String ABI = org.fisco.bcos.sdk.utils.StringUtils.joinAll("", ABI_ARRAY);

    public static final String FUNC_APPLYPRODUCTCERTIFICATE = "applyProductCertificate";

    public static final String FUNC_APPROVEPRODUCTCERTIFICATE = "approveProductCertificate";

    public static final String FUNC_CHANGEPRODUCTCERTIFICATE = "changeProductCertificate";

    public static final String FUNC_GETPRODUCTCERTIFICATE = "getProductCertificate";

    public static final String FUNC_PRODUCTCERTIFICATES = "productCertificates";

    public static final Event PRODUCTCERTIFICATEAPPLIED_EVENT = new Event("ProductCertificateApplied", 
            Arrays.<TypeReference<?>>asList(new TypeReference<Address>() {}, new TypeReference<Utf8String>() {}));
    ;

    public static final Event PRODUCTCERTIFICATEAPPROVED_EVENT = new Event("ProductCertificateApproved", 
            Arrays.<TypeReference<?>>asList(new TypeReference<Address>(true) {}, new TypeReference<Address>(true) {}));
    ;

    public static final Event PRODUCTCERTIFICATECHANGED_EVENT = new Event("ProductCertificateChanged", 
            Arrays.<TypeReference<?>>asList(new TypeReference<Address>() {}, new TypeReference<Utf8String>() {}));
    ;

    protected Product(String contractAddress, Client client, CryptoKeyPair credential) {
        super(getBinary(client.getCryptoSuite()), contractAddress, client, credential);
    }

    public static String getBinary(CryptoSuite cryptoSuite) {
        return (cryptoSuite.getCryptoTypeConfig() == CryptoType.ECDSA_TYPE ? BINARY : SM_BINARY);
    }

    public List<ProductCertificateAppliedEventResponse> getProductCertificateAppliedEvents(TransactionReceipt transactionReceipt) {
        List<EventValuesWithLog> valueList = extractEventParametersWithLog(PRODUCTCERTIFICATEAPPLIED_EVENT, transactionReceipt);
        ArrayList<ProductCertificateAppliedEventResponse> responses = new ArrayList<ProductCertificateAppliedEventResponse>(valueList.size());
        for (EventValuesWithLog eventValues : valueList) {
            ProductCertificateAppliedEventResponse typedResponse = new ProductCertificateAppliedEventResponse();
            typedResponse.log = eventValues.getLog();
            typedResponse.productAddress = (String) eventValues.getNonIndexedValues().get(0).getValue();
            typedResponse.name = (String) eventValues.getNonIndexedValues().get(1).getValue();
            responses.add(typedResponse);
        }
        return responses;
    }

    public void subscribeProductCertificateAppliedEvent(String fromBlock, String toBlock, List<String> otherTopics, EventCallback callback) {
        String topic0 = eventEncoder.encode(PRODUCTCERTIFICATEAPPLIED_EVENT);
        subscribeEvent(ABI,BINARY,topic0,fromBlock,toBlock,otherTopics,callback);
    }

    public void subscribeProductCertificateAppliedEvent(EventCallback callback) {
        String topic0 = eventEncoder.encode(PRODUCTCERTIFICATEAPPLIED_EVENT);
        subscribeEvent(ABI,BINARY,topic0,callback);
    }

    public List<ProductCertificateApprovedEventResponse> getProductCertificateApprovedEvents(TransactionReceipt transactionReceipt) {
        List<EventValuesWithLog> valueList = extractEventParametersWithLog(PRODUCTCERTIFICATEAPPROVED_EVENT, transactionReceipt);
        ArrayList<ProductCertificateApprovedEventResponse> responses = new ArrayList<ProductCertificateApprovedEventResponse>(valueList.size());
        for (EventValuesWithLog eventValues : valueList) {
            ProductCertificateApprovedEventResponse typedResponse = new ProductCertificateApprovedEventResponse();
            typedResponse.log = eventValues.getLog();
            typedResponse.entityAddress = (String) eventValues.getIndexedValues().get(0).getValue();
            typedResponse.productAddress = (String) eventValues.getIndexedValues().get(1).getValue();
            responses.add(typedResponse);
        }
        return responses;
    }

    public void subscribeProductCertificateApprovedEvent(String fromBlock, String toBlock, List<String> otherTopics, EventCallback callback) {
        String topic0 = eventEncoder.encode(PRODUCTCERTIFICATEAPPROVED_EVENT);
        subscribeEvent(ABI,BINARY,topic0,fromBlock,toBlock,otherTopics,callback);
    }

    public void subscribeProductCertificateApprovedEvent(EventCallback callback) {
        String topic0 = eventEncoder.encode(PRODUCTCERTIFICATEAPPROVED_EVENT);
        subscribeEvent(ABI,BINARY,topic0,callback);
    }

    public List<ProductCertificateChangedEventResponse> getProductCertificateChangedEvents(TransactionReceipt transactionReceipt) {
        List<EventValuesWithLog> valueList = extractEventParametersWithLog(PRODUCTCERTIFICATECHANGED_EVENT, transactionReceipt);
        ArrayList<ProductCertificateChangedEventResponse> responses = new ArrayList<ProductCertificateChangedEventResponse>(valueList.size());
        for (EventValuesWithLog eventValues : valueList) {
            ProductCertificateChangedEventResponse typedResponse = new ProductCertificateChangedEventResponse();
            typedResponse.log = eventValues.getLog();
            typedResponse.productAddress = (String) eventValues.getNonIndexedValues().get(0).getValue();
            typedResponse.name = (String) eventValues.getNonIndexedValues().get(1).getValue();
            responses.add(typedResponse);
        }
        return responses;
    }

    public void subscribeProductCertificateChangedEvent(String fromBlock, String toBlock, List<String> otherTopics, EventCallback callback) {
        String topic0 = eventEncoder.encode(PRODUCTCERTIFICATECHANGED_EVENT);
        subscribeEvent(ABI,BINARY,topic0,fromBlock,toBlock,otherTopics,callback);
    }

    public void subscribeProductCertificateChangedEvent(EventCallback callback) {
        String topic0 = eventEncoder.encode(PRODUCTCERTIFICATECHANGED_EVENT);
        subscribeEvent(ABI,BINARY,topic0,callback);
    }

    public TransactionReceipt applyProductCertificate(String _productAddress, String _name, String _certificateType, String _certificateMaterial, String _enterpriseName) {
        final Function function = new Function(
                FUNC_APPLYPRODUCTCERTIFICATE, 
                Arrays.<Type>asList(new Address(_productAddress),
                new Utf8String(_name),
                new Utf8String(_certificateType),
                new Utf8String(_certificateMaterial),
                new Utf8String(_enterpriseName)),
                Collections.<TypeReference<?>>emptyList());
        return executeTransaction(function);
    }

    public void applyProductCertificate(String _productAddress, String _name, String _certificateType, String _certificateMaterial, String _enterpriseName, TransactionCallback callback) {
        final Function function = new Function(
                FUNC_APPLYPRODUCTCERTIFICATE, 
                Arrays.<Type>asList(new Address(_productAddress),
                new Utf8String(_name),
                new Utf8String(_certificateType),
                new Utf8String(_certificateMaterial),
                new Utf8String(_enterpriseName)),
                Collections.<TypeReference<?>>emptyList());
        asyncExecuteTransaction(function, callback);
    }

    public String getSignedTransactionForApplyProductCertificate(String _productAddress, String _name, String _certificateType, String _certificateMaterial, String _enterpriseName) {
        final Function function = new Function(
                FUNC_APPLYPRODUCTCERTIFICATE, 
                Arrays.<Type>asList(new Address(_productAddress),
                new Utf8String(_name),
                new Utf8String(_certificateType),
                new Utf8String(_certificateMaterial),
                new Utf8String(_enterpriseName)),
                Collections.<TypeReference<?>>emptyList());
        return createSignedTransaction(function);
    }

    public Tuple5<String, String, String, String, String> getApplyProductCertificateInput(TransactionReceipt transactionReceipt) {
        String data = transactionReceipt.getInput().substring(10);
        final Function function = new Function(FUNC_APPLYPRODUCTCERTIFICATE, 
                Arrays.<Type>asList(), 
                Arrays.<TypeReference<?>>asList(new TypeReference<Address>() {}, new TypeReference<Utf8String>() {}, new TypeReference<Utf8String>() {}, new TypeReference<Utf8String>() {}, new TypeReference<Utf8String>() {}));
        List<Type> results = FunctionReturnDecoder.decode(data, function.getOutputParameters());
        return new Tuple5<String, String, String, String, String>(

                (String) results.get(0).getValue(), 
                (String) results.get(1).getValue(), 
                (String) results.get(2).getValue(), 
                (String) results.get(3).getValue(), 
                (String) results.get(4).getValue()
                );
    }

    public TransactionReceipt approveProductCertificate(String _address, BigInteger _index) {
        final Function function = new Function(
                FUNC_APPROVEPRODUCTCERTIFICATE, 
                Arrays.<Type>asList(new Address(_address),
                new Uint256(_index)),
                Collections.<TypeReference<?>>emptyList());
        return executeTransaction(function);
    }

    public void approveProductCertificate(String _address, BigInteger _index, TransactionCallback callback) {
        final Function function = new Function(
                FUNC_APPROVEPRODUCTCERTIFICATE, 
                Arrays.<Type>asList(new Address(_address),
                new Uint256(_index)),
                Collections.<TypeReference<?>>emptyList());
        asyncExecuteTransaction(function, callback);
    }

    public String getSignedTransactionForApproveProductCertificate(String _address, BigInteger _index) {
        final Function function = new Function(
                FUNC_APPROVEPRODUCTCERTIFICATE, 
                Arrays.<Type>asList(new Address(_address),
                new Uint256(_index)),
                Collections.<TypeReference<?>>emptyList());
        return createSignedTransaction(function);
    }

    public Tuple2<String, BigInteger> getApproveProductCertificateInput(TransactionReceipt transactionReceipt) {
        String data = transactionReceipt.getInput().substring(10);
        final Function function = new Function(FUNC_APPROVEPRODUCTCERTIFICATE, 
                Arrays.<Type>asList(), 
                Arrays.<TypeReference<?>>asList(new TypeReference<Address>() {}, new TypeReference<Uint256>() {}));
        List<Type> results = FunctionReturnDecoder.decode(data, function.getOutputParameters());
        return new Tuple2<String, BigInteger>(

                (String) results.get(0).getValue(), 
                (BigInteger) results.get(1).getValue()
                );
    }

    public TransactionReceipt changeProductCertificate(String _address, BigInteger _index, String _name, String _certificateType, String _certificateMaterial, String _enterpriseName) {
        final Function function = new Function(
                FUNC_CHANGEPRODUCTCERTIFICATE, 
                Arrays.<Type>asList(new Address(_address),
                new Uint256(_index),
                new Utf8String(_name),
                new Utf8String(_certificateType),
                new Utf8String(_certificateMaterial),
                new Utf8String(_enterpriseName)),
                Collections.<TypeReference<?>>emptyList());
        return executeTransaction(function);
    }

    public void changeProductCertificate(String _address, BigInteger _index, String _name, String _certificateType, String _certificateMaterial, String _enterpriseName, TransactionCallback callback) {
        final Function function = new Function(
                FUNC_CHANGEPRODUCTCERTIFICATE, 
                Arrays.<Type>asList(new Address(_address),
                new Uint256(_index),
                new Utf8String(_name),
                new Utf8String(_certificateType),
                new Utf8String(_certificateMaterial),
                new Utf8String(_enterpriseName)),
                Collections.<TypeReference<?>>emptyList());
        asyncExecuteTransaction(function, callback);
    }

    public String getSignedTransactionForChangeProductCertificate(String _address, BigInteger _index, String _name, String _certificateType, String _certificateMaterial, String _enterpriseName) {
        final Function function = new Function(
                FUNC_CHANGEPRODUCTCERTIFICATE, 
                Arrays.<Type>asList(new Address(_address),
                new Uint256(_index),
                new Utf8String(_name),
                new Utf8String(_certificateType),
                new Utf8String(_certificateMaterial),
                new Utf8String(_enterpriseName)),
                Collections.<TypeReference<?>>emptyList());
        return createSignedTransaction(function);
    }

    public Tuple6<String, BigInteger, String, String, String, String> getChangeProductCertificateInput(TransactionReceipt transactionReceipt) {
        String data = transactionReceipt.getInput().substring(10);
        final Function function = new Function(FUNC_CHANGEPRODUCTCERTIFICATE, 
                Arrays.<Type>asList(), 
                Arrays.<TypeReference<?>>asList(new TypeReference<Address>() {}, new TypeReference<Uint256>() {}, new TypeReference<Utf8String>() {}, new TypeReference<Utf8String>() {}, new TypeReference<Utf8String>() {}, new TypeReference<Utf8String>() {}));
        List<Type> results = FunctionReturnDecoder.decode(data, function.getOutputParameters());
        return new Tuple6<String, BigInteger, String, String, String, String>(

                (String) results.get(0).getValue(), 
                (BigInteger) results.get(1).getValue(), 
                (String) results.get(2).getValue(), 
                (String) results.get(3).getValue(), 
                (String) results.get(4).getValue(), 
                (String) results.get(5).getValue()
                );
    }

    public Tuple7<String, String, String, String, BigInteger, Boolean, String> getProductCertificate(String _address, BigInteger _index) throws ContractException {
        final Function function = new Function(FUNC_GETPRODUCTCERTIFICATE, 
                Arrays.<Type>asList(new Address(_address),
                new Uint256(_index)),
                Arrays.<TypeReference<?>>asList(new TypeReference<Address>() {}, new TypeReference<Utf8String>() {}, new TypeReference<Utf8String>() {}, new TypeReference<Utf8String>() {}, new TypeReference<Uint256>() {}, new TypeReference<Bool>() {}, new TypeReference<Utf8String>() {}));
        List<Type> results = executeCallWithMultipleValueReturn(function);
        return new Tuple7<String, String, String, String, BigInteger, Boolean, String>(
                (String) results.get(0).getValue(), 
                (String) results.get(1).getValue(), 
                (String) results.get(2).getValue(), 
                (String) results.get(3).getValue(), 
                (BigInteger) results.get(4).getValue(), 
                (Boolean) results.get(5).getValue(), 
                (String) results.get(6).getValue());
    }

    public Tuple7<String, String, String, String, String, BigInteger, Boolean> productCertificates(String param0, BigInteger param1) throws ContractException {
        final Function function = new Function(FUNC_PRODUCTCERTIFICATES, 
                Arrays.<Type>asList(new Address(param0),
                new Uint256(param1)),
                Arrays.<TypeReference<?>>asList(new TypeReference<Address>() {}, new TypeReference<Utf8String>() {}, new TypeReference<Utf8String>() {}, new TypeReference<Utf8String>() {}, new TypeReference<Utf8String>() {}, new TypeReference<Uint256>() {}, new TypeReference<Bool>() {}));
        List<Type> results = executeCallWithMultipleValueReturn(function);
        return new Tuple7<String, String, String, String, String, BigInteger, Boolean>(
                (String) results.get(0).getValue(), 
                (String) results.get(1).getValue(), 
                (String) results.get(2).getValue(), 
                (String) results.get(3).getValue(), 
                (String) results.get(4).getValue(), 
                (BigInteger) results.get(5).getValue(), 
                (Boolean) results.get(6).getValue());
    }

    public static Product load(String contractAddress, Client client, CryptoKeyPair credential) {
        return new Product(contractAddress, client, credential);
    }

    public static Product deploy(Client client, CryptoKeyPair credential) throws ContractException {
        return deploy(Product.class, client, credential, getBinary(client.getCryptoSuite()), "");
    }

    public static class ProductCertificateAppliedEventResponse {
        public TransactionReceipt.Logs log;

        public String productAddress;

        public String name;
    }

    public static class ProductCertificateApprovedEventResponse {
        public TransactionReceipt.Logs log;

        public String entityAddress;

        public String productAddress;
    }

    public static class ProductCertificateChangedEventResponse {
        public TransactionReceipt.Logs log;

        public String productAddress;

        public String name;
    }
}
